#include "networkthread.h"
#include <QDebug>
#include <QEventLoop>
#include <QTimer>
#include <QMutexLocker>

NetworkThread::NetworkThread(QObject *parent)
    : QThread(parent)
    , m_webSocketClient(nullptr)
    , m_running(false)
    , m_connected(false)
    , m_configSet(false)
    , m_messagesSent(0)
    , m_messagesReceived(0)
    , m_lastPingTime(0)
{
    qDebug() << "NetworkThread: 网络线程创建";
}

NetworkThread::~NetworkThread()
{
    disconnectAndStop();
    qDebug() << "NetworkThread: 网络线程销毁";
}

void NetworkThread::connectToGameServer(const NetworkWebSocketConfig &config)
{
    QMutexLocker locker(&m_stateMutex);
    m_config = config;
    m_configSet = true;

    qDebug() << "NetworkThread: 设置服务器配置，准备连接";

    if (!isRunning()) {
        start();
    }
}

void NetworkThread::sendMessage(const QJsonObject &message)
{
    QMutexLocker locker(&m_messageMutex);
    m_pendingMessages.append(message);
    m_messageCondition.wakeOne();

    qDebug() << "NetworkThread: 添加消息到发送队列，类型:" << message["type"].toString();
}

void NetworkThread::disconnectAndStop()
{
    qDebug() << "NetworkThread: 请求断开连接并停止线程";

    {
        QMutexLocker locker(&m_stateMutex);
        m_running = false;
    }

    m_messageCondition.wakeAll();

    if (isRunning()) {
        wait(5000); // 等待5秒
        if (isRunning()) {
            qWarning() << "NetworkThread: 强制终止线程";
            terminate();
            wait(1000);
        }
    }
}

bool NetworkThread::isConnected() const
{
    QMutexLocker locker(&m_stateMutex);
    return m_connected;
}

void NetworkThread::run()
{
    qDebug() << "NetworkThread: 网络线程开始运行";

    {
        QMutexLocker locker(&m_stateMutex);
        m_running = true;
    }

    // 初始化网络组件
    initializeNetworkComponents();

    // 如果配置已设置，立即连接
    if (m_configSet && m_webSocketClient) {
        qDebug() << "NetworkThread: 开始连接到游戏服务器";

        // 转换配置格式
        WebSocketClient::ConnectionConfig wsConfig;
        wsConfig.serverUrl = m_config.url;
        wsConfig.gameToken = m_config.gameToken;
        wsConfig.sessionToken = m_config.sessionToken;
        wsConfig.playerId = m_config.playerId;
        wsConfig.heartbeatInterval = m_config.heartbeatInterval;
        wsConfig.reconnectInterval = 5000;
        wsConfig.maxReconnectAttempts = m_config.maxReconnectAttempts;
        wsConfig.enableCompression = true;
        wsConfig.enableSSL = m_config.url.startsWith("wss://");
        wsConfig.protocols << "snake-game-v1";

        // 直接使用WebSocketClient连接
        m_webSocketClient->connectToServer(wsConfig);
    }

    // 事件循环
    QEventLoop eventLoop;

    // 设置消息处理定时器（在网络线程内消费发送队列，确保socket操作在正确线程）
    QTimer messageTimer;
    messageTimer.setInterval(10); // 10ms检查一次
    connect(&messageTimer, &QTimer::timeout, [this]() {
        QMutexLocker locker(&m_messageMutex);
        if (m_pendingMessages.isEmpty() || !m_webSocketClient || !m_connected) {
            return;
        }
        while (!m_pendingMessages.isEmpty()) {
            QJsonObject message = m_pendingMessages.takeFirst();
            QString messageType = message["type"].toString();
            qDebug() << "NetworkThread: 发送消息(网络线程)，类型:" << messageType;
            m_webSocketClient->sendMessage(message); // 在网络线程内调用，避免QSocketNotifier跨线程
            {
                QMutexLocker statLocker(&m_stateMutex);
                m_messagesSent++;
            }
        }
    });
    messageTimer.start();

    qDebug() << "NetworkThread: 启动标准事件循环，确保QTimer正常工作";

    // 使用标准的事件循环，确保QTimer和信号槽正常工作
    exec();

    // 清理网络组件
    cleanupNetworkComponents();

    qDebug() << "NetworkThread: 网络线程结束运行";
}

void NetworkThread::initializeNetworkComponents()
{
    qDebug() << "NetworkThread: 初始化网络组件";

    // 创建WebSocket客户端（在网络线程中）
    m_webSocketClient = new WebSocketClient();

    // 连接WebSocket信号
    connect(m_webSocketClient, &WebSocketClient::connected,
            this, &NetworkThread::onWebSocketConnected);
    connect(m_webSocketClient, &WebSocketClient::disconnected,
            this, &NetworkThread::onWebSocketDisconnected);
    connect(m_webSocketClient, &WebSocketClient::authenticated,
            this, &NetworkThread::onWebSocketAuthenticated);
    connect(m_webSocketClient, &WebSocketClient::authenticationFailed,
            this, &NetworkThread::onWebSocketAuthenticationFailed);
    connect(m_webSocketClient, &WebSocketClient::messageReceived,
            this, &NetworkThread::onWebSocketMessageReceived);
    connect(m_webSocketClient, &WebSocketClient::connectionError,
            this, &NetworkThread::onWebSocketError);

    qDebug() << "NetworkThread: 网络组件初始化完成";
}

void NetworkThread::cleanupNetworkComponents()
{
    qDebug() << "NetworkThread: 清理网络组件";

    if (m_webSocketClient) {
        m_webSocketClient->disconnectFromServer();
        m_webSocketClient->deleteLater();
        m_webSocketClient = nullptr;
    }

    // m_gameManager已设置为nullptr，无需清理

    qDebug() << "NetworkThread: 网络组件清理完成";
}

void NetworkThread::onWebSocketConnected()
{
    qDebug() << "NetworkThread: WebSocket连接成功";

    {
        QMutexLocker locker(&m_stateMutex);
        m_connected = true;
    }

    emit connected();
}

void NetworkThread::onWebSocketDisconnected()
{
    qDebug() << "NetworkThread: WebSocket连接断开";

    {
        QMutexLocker locker(&m_stateMutex);
        m_connected = false;
    }

    emit disconnected("WebSocket连接断开");
}

void NetworkThread::onWebSocketAuthenticated(const QJsonObject &playerInfo)
{
    qDebug() << "NetworkThread: WebSocket认证成功";
    qDebug() << "  玩家信息:" << playerInfo;

    // 认证成功后，等待用户选择游戏模式
    qDebug() << "NetworkThread: 认证成功，等待用户选择游戏模式";

    // 注意：移除了过早的定时器设置，等待用户选择游戏模式后再设置定时器

    // 记录临时player_id（若提供）
    if (playerInfo.contains("player_id")) {
        m_wsPlayerId = playerInfo["player_id"].toString();
        qDebug() << "NetworkThread: 缓存WebSocket临时player_id:" << m_wsPlayerId;
    }

    emit authenticated();
}

void NetworkThread::onWebSocketAuthenticationFailed(const QString &error)
{
    qWarning() << "NetworkThread: WebSocket认证失败:" << error;

    emit authenticationFailed(error);
}

void NetworkThread::onWebSocketMessageReceived(const QJsonObject &message)
{
    QString messageType = message["type"].toString();

    qDebug() << "=== NetworkThread::onWebSocketMessageReceived 被调用 ===";
    qDebug() << "NetworkThread: 收到消息，类型:" << messageType;
    // 降噪：不再打印完整JSON，按类型打印摘要
    if (messageType == "game_state_update") {
        QJsonObject data = message.value("data").toObject();
        qDebug() << "data.keys():" << data.keys();
        QJsonArray snakes = data.value("snakes").toArray();
        QJsonArray foods  = data.value("foods").toArray();
        qDebug() << "snakes数组大小:" << snakes.size();
        qDebug() << "foods数组大小:" << foods.size();
    } else if (messageType == "ping" || messageType == "pong") {
        qDebug() << "NetworkThread: 心跳消息，timestamp:" << message.value("timestamp").toVariant();
    } else if (messageType == "error") {
        handleErrorMessage(message);
        return; // 避免在下方的其他分支重复处理同一条错误消息
    } else {
        qDebug() << "NetworkThread: message keys:" << message.keys();
    }

    {
        QMutexLocker locker(&m_stateMutex);
        m_messagesReceived++;
    }

    // 处理特殊消息类型
    if (messageType == "room_created") {
        bool success = message["success"].toBool();
        if (success) {
            QString roomId = message["room_id"].toString();
            m_lastRoomId = roomId;
            qDebug() << "NetworkThread: 房间创建成功，room_id=" << roomId;
            qDebug() << "NetworkThread: 当前状态 - m_startGameRequested:" << m_startGameRequested << ", m_gameStarted:" << m_gameStarted;

            // 立刻join_room并直接尝试start_game（幂等），不依赖singleShot
            if (!m_startGameRequested && !m_gameStarted) {
                QJsonObject joinRoom{{"type","join_room"},{"room_id",roomId}};
                sendMessage(joinRoom);
                qDebug() << "NetworkThread: 发送join_room消息";

                QJsonObject startGame{{"type","start_game"},{"room_id",roomId}};
                sendMessage(startGame);
                qDebug() << "NetworkThread: 发送start_game消息";

                m_startGameRequested = true;
                qDebug() << "NetworkThread: 已尝试自动start_game (from room_created)";
            } else {
                qDebug() << "NetworkThread: 跳过start_game - 已请求或已开始";
            }
        } else {
            qWarning() << "NetworkThread: 房间创建失败:" << message["message"].toString();
        }
    }
    else if (messageType == "join_room_response") {
        bool success = message["success"].toBool();
        qDebug() << "NetworkThread: join_room_response success=" << success;
        if (success && !m_gameStarted && !m_gameStartBlocked) {
            QString roomId = message.contains("room_id") ? message["room_id"].toString() : m_lastRoomId;
            if (!roomId.isEmpty() && !m_startGameRequested) {
                QJsonObject startGame{{"type","start_game"},{"room_id",roomId}};
                sendMessage(startGame);
                m_startGameRequested = true;
                qDebug() << "NetworkThread: 已尝试自动start_game (from join_room_response)";
            } else {
                qDebug() << "NetworkThread: 跳过start_game - 已请求或已阻止";
            }
        }
    }
    else if (messageType == "room_joined") {
        // 兼容某些服务端先发room_joined再发room_created的顺序
        QJsonObject data = message.value("data").toObject();
        QJsonObject roomInfo = data.value("room_info").toObject();
        QString roomId = roomInfo.value("room_id").toString();
        if (!roomId.isEmpty()) {
            m_lastRoomId = roomId;
            m_currentRoomId = roomId;  // 缓存当前房间ID上下文
            qDebug() << "NetworkThread: room_joined，room_id=" << roomId;
            qDebug() << "NetworkThread: 当前状态 - m_startGameRequested:" << m_startGameRequested << ", m_gameStarted:" << m_gameStarted;

            // 打印ID对比，用于诊断NO_PERMISSION问题
            QString creatorId = roomInfo.value("creator_id").toString();
            qDebug() << "NetworkThread: ID对比 - 本地playerId:" << m_config.playerId
                     << "WebSocket playerId:" << m_wsPlayerId
                     << "房间creatorId:" << creatorId;

            bool amCreator = (creatorId == m_config.playerId || creatorId == m_wsPlayerId);

            // 严格的start_game控制：只有创建者且未被阻止时才发送
            if (!m_gameStarted && !m_startGameRequested && !m_gameStartBlocked && amCreator) {
                QJsonObject startGame{{"type","start_game"},{"room_id",roomId}};
                sendMessage(startGame);
                qDebug() << "NetworkThread: 发送start_game消息 (from room_joined, 创建者)";
                m_startGameRequested = true;
                qDebug() << "NetworkThread: 已尝试自动start_game (from room_joined)";
            } else {
                QString reason = m_gameStartBlocked ? "已被阻止" :
                               m_gameStarted ? "游戏已开始" :
                               m_startGameRequested ? "已请求过" :
                               !amCreator ? "非创建者" : "未知原因";
                qDebug() << "NetworkThread: 跳过start_game -" << reason;
            }
        }
    }
    else if (messageType == "game_started") {
        qDebug() << "NetworkThread: 游戏已开始 - 永久阻止后续start_game";
        m_gameStarted = true;
        m_startGameRequested = true;  // 防止后续重复发送start_game
        m_gameStartBlocked = true;    // 永久阻止start_game重发

        // 清理发送队列中的残留 start_game 消息
        QMutexLocker locker(&m_messageMutex);
        int originalSize = m_pendingMessages.size();
        m_pendingMessages.erase(
            std::remove_if(m_pendingMessages.begin(), m_pendingMessages.end(),
                [](const QJsonObject& msg) {
                    return msg["type"].toString() == "start_game";
                }),
            m_pendingMessages.end());
        int removedCount = originalSize - m_pendingMessages.size();
        if (removedCount > 0) {
            qDebug() << "NetworkThread: 清理了" << removedCount << "个残留的start_game消息";
        }
    }
    else if (messageType == "game_state_update") {
        qDebug() << "NetworkThread: 收到游戏状态更新";
    }
    else if (messageType == "error") {
        handleErrorMessage(message);
        return; // 避免重复处理
    }
    else if (messageType == "pong") {
        qDebug() << "NetworkThread: 收到服务器pong响应";
    }
    else if (messageType == "game_info") {
        qDebug() << "NetworkThread: 收到游戏信息:" << message;
    }
    else if (messageType == "player_joined") {
        qDebug() << "NetworkThread: 玩家加入游戏:" << message;
    }
    else if (messageType == "game_ready") {
        qDebug() << "NetworkThread: 游戏准备就绪:" << message;
    }
    else if (messageType == "welcome") {
        qDebug() << "NetworkThread: 收到欢迎消息";
        // 欢迎消息已在WebSocketClient中处理，这里只记录
    }
    else if (messageType == "authentication_result") {
        qDebug() << "NetworkThread: 收到认证结果";
        // 认证结果已在WebSocketClient中处理，这里只记录
    }
    else if (messageType == "start_game_response") {
        bool success = message["success"].toBool();
        qDebug() << "NetworkThread: start_game响应，成功:" << success;
        if (success) {
            m_gameStarted = true;
            qDebug() << "  游戏启动成功，标记m_gameStarted=true";
        } else {
            QString error = message["error"].toString();
            if (error == "NO_PERMISSION" || error.contains("already")) {
                qDebug() << "  游戏已经开始，忽略重复start_game错误";
                m_gameStarted = true; // 即使是重复错误，也认为游戏已启动
            } else {
                qWarning() << "  start_game失败:" << error;
            }
        }
    }
    else if (messageType == "room_state_change") {
        QJsonObject data = message["data"].toObject();
        int newState = data.contains("new_state") ? data["new_state"].toInt()
                                                   : message["new_state"].toInt();
        qDebug() << "NetworkThread: 房间状态变化，新状态:" << newState;

        // 状态映射：0=WAITING, 1=PLAYING, 2=PAUSED, 3=FINISHED
        QString stateText;
        switch (newState) {
            case 0: stateText = "等待中"; break;
            case 1: stateText = "游戏中"; break;
            case 2: stateText = "暂停"; break;
            case 3: stateText = "已结束"; break;
            default: stateText = "未知状态"; break;
        }
        qDebug() << "  状态含义:" << stateText;

        if (newState == 1) { // 游戏中状态
            m_gameStarted = true;
            m_startGameRequested = true;  // 防止后续重复发送start_game
            m_gameStartBlocked = true;    // 永久阻止start_game重发
            qDebug() << "  房间进入游戏状态，永久阻止后续start_game";
        }
    }
    else if (messageType == "error") {
        handleErrorMessage(message);
        return; // 避免重复处理
    }
    else {
        qDebug() << "NetworkThread: 处理消息类型:" << messageType;
        // 不再标记为"未处理"，因为有些消息类型是正常的
    }

    // 发送到主线程
    emit gameMessageReceived(message);
}

void NetworkThread::onWebSocketError(const QString &error)
{
    qCritical() << "NetworkThread: WebSocket错误:" << error;

    emit connectionError(error);
}

void NetworkThread::processPendingMessages()
{
    QMutexLocker locker(&m_messageMutex);

    if (m_pendingMessages.isEmpty() || !m_webSocketClient || !m_connected) {
        return;
    }

    while (!m_pendingMessages.isEmpty()) {
        QJsonObject message = m_pendingMessages.takeFirst();

        // 不在消息体内强行注入自定义认证字段，遵循文档（鉴权在握手与authenticate中完成）
        QString messageType = message["type"].toString();

        // 自动补齐 room_id（如消息需要且未填）
        if ((messageType == "change_direction" || messageType == "start_game" || messageType == "join_room")
            && !message.contains("room_id") && !m_lastRoomId.isEmpty()) {
            const_cast<QJsonObject&>(message)["room_id"] = m_lastRoomId;
        }

        qDebug() << "NetworkThread: 发送消息(网络线程)，类型:" << messageType;

        // 通过WebSocketClient发送（在网络线程内调用）
        m_webSocketClient->sendMessage(message);

        // 更新统计信息
        {
            QMutexLocker statLocker(&m_stateMutex);
            m_messagesSent++;
        }
    }
}


void NetworkThread::startSinglePlayerGame()
{
    qDebug() << "NetworkThread: 用户选择单人模式，等待渲染管线就绪";

    // 重置状态标志，确保幂等逻辑正确工作
    m_startGameRequested = false;
    m_gameStarted = false;
    m_gameStartBlocked = false;  // 新增：游戏启动永久阻止标志
    m_lastRoomId.clear();
    m_currentRoomId.clear();
    m_renderPipelineReady = false;  // 新增：渲染管线就绪标志
    qDebug() << "NetworkThread: 重置游戏状态标志";

    // 缓存create_room消息，等待渲染管线就绪后发送
    m_pendingCreateRoomMessage = QJsonObject();
    m_pendingCreateRoomMessage["type"] = "create_room";
    QJsonObject roomConfig;
    roomConfig["max_players"] = 1;
    roomConfig["game_mode"] = "classic";
    roomConfig["private"] = false;
    roomConfig["room_name"] = QString("单人房_%1").arg(m_config.playerName);
    roomConfig["map_width"] = 40;
    roomConfig["map_height"] = 30;
    roomConfig["game_speed_ms"] = 100;
    roomConfig["enable_walls"] = true;
    roomConfig["enable_special_foods"] = true;
    m_pendingCreateRoomMessage["room_config"] = roomConfig;

    qDebug() << "NetworkThread: create_room消息已缓存，等待渲染管线就绪信号";
}

void NetworkThread::onRenderPipelineReady()
{
    qDebug() << "NetworkThread: 收到渲染管线就绪信号";
    m_renderPipelineReady = true;

    // 打印WebSocket连接诊断信息
    if (m_webSocketClient) {
        qDebug() << "WebSocket连接诊断:";
        qDebug() << "  WebSocketClient实例:" << m_webSocketClient;
        qDebug() << "  连接状态:" << (m_webSocketClient->isConnected() ? "已连接" : "未连接");
        qDebug() << "  本地playerId:" << m_config.playerId;
        qDebug() << "  WebSocket playerId:" << m_wsPlayerId;
    }

    // 如果有缓存的create_room消息，现在发送
    if (!m_pendingCreateRoomMessage.isEmpty()) {
        qDebug() << "NetworkThread: 渲染管线就绪，发送缓存的create_room消息";
        sendMessage(m_pendingCreateRoomMessage);
        m_pendingCreateRoomMessage = QJsonObject();  // 清空缓存
    }
}

void NetworkThread::handleErrorMessage(const QJsonObject &message)
{
    // 统一处理错误消息，兼容多种错误格式
    QString errorCode;
    QString errorMessage;
    QString errorPlayerId;

    // 尝试从不同的字段获取错误信息
    // 格式1：顶层扁平格式 {"type": "error", "error": "code", "message": "msg"}
    if (message.contains("error") && message.contains("message")) {
        errorCode = message["error"].toString();
        errorMessage = message["message"].toString();
    }

    // 格式2：data包裹格式 {"type": "error", "data": {"error_code": "code", "error_message": "msg"}}
    if (message.contains("data")) {
        QJsonObject payload = message["data"].toObject();
        if (payload.contains("error_code")) {
            errorCode = payload["error_code"].toString();
        }
        if (payload.contains("error_message")) {
            errorMessage = payload["error_message"].toString();
        }
        if (payload.contains("player_id")) {
            errorPlayerId = payload["player_id"].toString();
        }
    }

    // 如果还没有获取到错误信息，尝试其他字段
    if (errorCode.isEmpty() && message.contains("error_code")) {
        errorCode = message["error_code"].toString();
    }
    if (errorMessage.isEmpty() && message.contains("error_message")) {
        errorMessage = message["error_message"].toString();
    }

    // 记录错误信息
    qWarning() << "NetworkThread: 服务器错误 - code:" << errorCode << "message:" << errorMessage;

    // 如果有详细信息，打印诊断信息
    if (!errorPlayerId.isEmpty()) {
        qWarning() << "NetworkThread: 错误详情 - player_id:" << errorPlayerId
                   << "本地player_id:" << m_config.playerId;
    }

    // 特殊错误处理
    if (errorCode == "NO_PERMISSION") {
        m_gameStartBlocked = true;  // 永久阻止start_game重发
        if (m_gameStarted) {
            qDebug() << "  NO_PERMISSION错误（游戏已开始后的延迟错误，静默处理）";
            return; // 静默处理，不发出错误信号
        } else {
            qDebug() << "  NO_PERMISSION错误 - 永久阻止start_game，但继续渲染";
        }
    }

    // 发出错误信号到UI层
    QString displayMessage = errorMessage.isEmpty() ? errorCode : errorMessage;
    if (!errorCode.isEmpty() && !errorMessage.isEmpty()) {
        emit gameError(QString("服务器错误 %1: %2").arg(errorCode, displayMessage));
    } else if (!displayMessage.isEmpty()) {
        emit gameError(QString("服务器错误: %1").arg(displayMessage));
    } else {
        emit gameError("未知服务器错误");
    }
}
